/*
	Copyright (c) 2010 <copyright holders>
	This source code is licensed under The MIT License,
	see the file LICENSE for details.
	*/

#ifndef NET_HPP
#define NET_HPP

#include <boost/asio/io_service.hpp>
#include <google/protobuf/message.h>

#include "ForwardDecls.hpp"
#include "MessageRegisters.hpp"
#include "NetVars.hpp"
#include "NetDefs.hpp"

namespace spelprog2 {
namespace net {

typedef boost::asio::io_service Service;

class Net : public MessageListenerRegistry<NetMessageInfo>
{
    NetVars vars;
    Service service;
    bool isServer_;
protected:
    explicit Net(bool isServer);
    Service & getService() { return service; }
public:
    virtual ~Net();

    virtual UserId getMyClientId() const = 0;

    //TODO: see if we can avoid exposing these (at least the non-const one)
    NetVars & getVars() { return vars; }
    const NetVars & getVars() const { return vars; }

    //! Is this a server? Generally avoid writing code relying on this function, but it's unavoidable in certain instances.
    bool isServer() const { return isServer_; }

    /**
        Runs one message handling iteration.
        */
    virtual void poll();

    /**
        Continously runs message handling. Note: As of yet somewhat undefined behaviour,
        will need to do more threading work if this is to work like intended.
        */
    virtual void run();

    //! Sends a message to any client user, or if receiver == SERVER_ID, the server user.
    virtual void sendToUser(const Message & msg, UserId receiver) = 0;

    //! Sends a message to everyone if this is a server (it is ignored for pure clients).
    virtual void sendToAll(const Message & msg) = 0;
};

struct NetMessageInfo {
    Net * net;
    UserId origin;
};

typedef MessageListenerRegistry<NetMessageInfo> NetMessageRegistry;
typedef MessageListener<NetMessageInfo> NetMessageListener;

}; //namespace net
}; //namespace spelprog2

#endif //NET_HPP
